{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Binary Classification - Home Team Win-Loss Modeling\n",
    "This short script imports logistic regression model class from sklearn and splits the data into test and validation sets to evaluate the performance on out of sample games."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.model_selection import train_test_split, cross_val_score\n",
    "from sklearn import preprocessing \n",
    "from sklearn.metrics import classification_report"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>HOME_LAST_GAME_OE</th>\n",
       "      <th>HOME_LAST_GAME_HOME_WIN_PCTG</th>\n",
       "      <th>HOME_NUM_REST_DAYS</th>\n",
       "      <th>HOME_LAST_GAME_AWAY_WIN_PCTG</th>\n",
       "      <th>HOME_LAST_GAME_TOTAL_WIN_PCTG</th>\n",
       "      <th>HOME_LAST_GAME_ROLLING_SCORING_MARGIN</th>\n",
       "      <th>HOME_LAST_GAME_ROLLING_OE</th>\n",
       "      <th>HOME_W</th>\n",
       "      <th>SEASON</th>\n",
       "      <th>AWAY_LAST_GAME_OE</th>\n",
       "      <th>AWAY_LAST_GAME_HOME_WIN_PCTG</th>\n",
       "      <th>AWAY_NUM_REST_DAYS</th>\n",
       "      <th>AWAY_LAST_GAME_AWAY_WIN_PCTG</th>\n",
       "      <th>AWAY_LAST_GAME_TOTAL_WIN_PCTG</th>\n",
       "      <th>AWAY_LAST_GAME_ROLLING_SCORING_MARGIN</th>\n",
       "      <th>AWAY_LAST_GAME_ROLLING_OE</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.555556</td>\n",
       "      <td>0.685714</td>\n",
       "      <td>3.0</td>\n",
       "      <td>0.444444</td>\n",
       "      <td>0.563380</td>\n",
       "      <td>9.333333</td>\n",
       "      <td>0.571405</td>\n",
       "      <td>1</td>\n",
       "      <td>2020-21</td>\n",
       "      <td>0.612903</td>\n",
       "      <td>0.250000</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.228571</td>\n",
       "      <td>0.239437</td>\n",
       "      <td>-2.000000</td>\n",
       "      <td>0.605315</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.573913</td>\n",
       "      <td>0.676471</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.444444</td>\n",
       "      <td>0.557143</td>\n",
       "      <td>-0.666667</td>\n",
       "      <td>0.589472</td>\n",
       "      <td>1</td>\n",
       "      <td>2020-21</td>\n",
       "      <td>0.500000</td>\n",
       "      <td>0.305556</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.303030</td>\n",
       "      <td>0.304348</td>\n",
       "      <td>-18.000000</td>\n",
       "      <td>0.512228</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.584746</td>\n",
       "      <td>0.666667</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.444444</td>\n",
       "      <td>0.550725</td>\n",
       "      <td>8.666667</td>\n",
       "      <td>0.640592</td>\n",
       "      <td>1</td>\n",
       "      <td>2020-21</td>\n",
       "      <td>0.612403</td>\n",
       "      <td>0.500000</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.428571</td>\n",
       "      <td>0.463768</td>\n",
       "      <td>0.666667</td>\n",
       "      <td>0.567718</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.609756</td>\n",
       "      <td>0.656250</td>\n",
       "      <td>4.0</td>\n",
       "      <td>0.444444</td>\n",
       "      <td>0.544118</td>\n",
       "      <td>11.333333</td>\n",
       "      <td>0.653327</td>\n",
       "      <td>1</td>\n",
       "      <td>2020-21</td>\n",
       "      <td>0.539568</td>\n",
       "      <td>0.500000</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.441176</td>\n",
       "      <td>0.470588</td>\n",
       "      <td>0.666667</td>\n",
       "      <td>0.570866</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.512397</td>\n",
       "      <td>0.354839</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.558824</td>\n",
       "      <td>0.461538</td>\n",
       "      <td>11.000000</td>\n",
       "      <td>0.596498</td>\n",
       "      <td>1</td>\n",
       "      <td>2020-21</td>\n",
       "      <td>0.727273</td>\n",
       "      <td>0.656250</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.457143</td>\n",
       "      <td>0.552239</td>\n",
       "      <td>17.333333</td>\n",
       "      <td>0.633081</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0.622951</td>\n",
       "      <td>0.645161</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.457143</td>\n",
       "      <td>0.545455</td>\n",
       "      <td>-0.666667</td>\n",
       "      <td>0.561996</td>\n",
       "      <td>1</td>\n",
       "      <td>2020-21</td>\n",
       "      <td>0.666667</td>\n",
       "      <td>0.735294</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.709677</td>\n",
       "      <td>0.723077</td>\n",
       "      <td>13.333333</td>\n",
       "      <td>0.644613</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>0.549020</td>\n",
       "      <td>0.633333</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.457143</td>\n",
       "      <td>0.538462</td>\n",
       "      <td>-18.333333</td>\n",
       "      <td>0.507124</td>\n",
       "      <td>1</td>\n",
       "      <td>2020-21</td>\n",
       "      <td>0.596639</td>\n",
       "      <td>0.500000</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.625000</td>\n",
       "      <td>0.562500</td>\n",
       "      <td>16.666667</td>\n",
       "      <td>0.599989</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>0.514019</td>\n",
       "      <td>0.620690</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.457143</td>\n",
       "      <td>0.531250</td>\n",
       "      <td>-26.666667</td>\n",
       "      <td>0.480273</td>\n",
       "      <td>1</td>\n",
       "      <td>2020-21</td>\n",
       "      <td>0.521739</td>\n",
       "      <td>0.387097</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.437500</td>\n",
       "      <td>0.412698</td>\n",
       "      <td>-7.000000</td>\n",
       "      <td>0.568524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>0.669565</td>\n",
       "      <td>0.774194</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.548387</td>\n",
       "      <td>0.661290</td>\n",
       "      <td>12.333333</td>\n",
       "      <td>0.569549</td>\n",
       "      <td>1</td>\n",
       "      <td>2020-21</td>\n",
       "      <td>0.458333</td>\n",
       "      <td>0.620690</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.470588</td>\n",
       "      <td>0.539683</td>\n",
       "      <td>-17.000000</td>\n",
       "      <td>0.489968</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>0.596774</td>\n",
       "      <td>0.766667</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.548387</td>\n",
       "      <td>0.655738</td>\n",
       "      <td>-4.666667</td>\n",
       "      <td>0.549138</td>\n",
       "      <td>1</td>\n",
       "      <td>2020-21</td>\n",
       "      <td>0.468468</td>\n",
       "      <td>0.620690</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.484848</td>\n",
       "      <td>0.548387</td>\n",
       "      <td>2.666667</td>\n",
       "      <td>0.540221</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   HOME_LAST_GAME_OE  HOME_LAST_GAME_HOME_WIN_PCTG  HOME_NUM_REST_DAYS  \\\n",
       "0           0.555556                      0.685714                 3.0   \n",
       "1           0.573913                      0.676471                 1.0   \n",
       "2           0.584746                      0.666667                 2.0   \n",
       "3           0.609756                      0.656250                 4.0   \n",
       "4           0.512397                      0.354839                 1.0   \n",
       "5           0.622951                      0.645161                 2.0   \n",
       "6           0.549020                      0.633333                 2.0   \n",
       "7           0.514019                      0.620690                 1.0   \n",
       "8           0.669565                      0.774194                 2.0   \n",
       "9           0.596774                      0.766667                 2.0   \n",
       "\n",
       "   HOME_LAST_GAME_AWAY_WIN_PCTG  HOME_LAST_GAME_TOTAL_WIN_PCTG  \\\n",
       "0                      0.444444                       0.563380   \n",
       "1                      0.444444                       0.557143   \n",
       "2                      0.444444                       0.550725   \n",
       "3                      0.444444                       0.544118   \n",
       "4                      0.558824                       0.461538   \n",
       "5                      0.457143                       0.545455   \n",
       "6                      0.457143                       0.538462   \n",
       "7                      0.457143                       0.531250   \n",
       "8                      0.548387                       0.661290   \n",
       "9                      0.548387                       0.655738   \n",
       "\n",
       "   HOME_LAST_GAME_ROLLING_SCORING_MARGIN  HOME_LAST_GAME_ROLLING_OE  HOME_W  \\\n",
       "0                               9.333333                   0.571405       1   \n",
       "1                              -0.666667                   0.589472       1   \n",
       "2                               8.666667                   0.640592       1   \n",
       "3                              11.333333                   0.653327       1   \n",
       "4                              11.000000                   0.596498       1   \n",
       "5                              -0.666667                   0.561996       1   \n",
       "6                             -18.333333                   0.507124       1   \n",
       "7                             -26.666667                   0.480273       1   \n",
       "8                              12.333333                   0.569549       1   \n",
       "9                              -4.666667                   0.549138       1   \n",
       "\n",
       "    SEASON  AWAY_LAST_GAME_OE  AWAY_LAST_GAME_HOME_WIN_PCTG  \\\n",
       "0  2020-21           0.612903                      0.250000   \n",
       "1  2020-21           0.500000                      0.305556   \n",
       "2  2020-21           0.612403                      0.500000   \n",
       "3  2020-21           0.539568                      0.500000   \n",
       "4  2020-21           0.727273                      0.656250   \n",
       "5  2020-21           0.666667                      0.735294   \n",
       "6  2020-21           0.596639                      0.500000   \n",
       "7  2020-21           0.521739                      0.387097   \n",
       "8  2020-21           0.458333                      0.620690   \n",
       "9  2020-21           0.468468                      0.620690   \n",
       "\n",
       "   AWAY_NUM_REST_DAYS  AWAY_LAST_GAME_AWAY_WIN_PCTG  \\\n",
       "0                 2.0                      0.228571   \n",
       "1                 2.0                      0.303030   \n",
       "2                 2.0                      0.428571   \n",
       "3                 2.0                      0.441176   \n",
       "4                 1.0                      0.457143   \n",
       "5                 1.0                      0.709677   \n",
       "6                 1.0                      0.625000   \n",
       "7                 1.0                      0.437500   \n",
       "8                 2.0                      0.470588   \n",
       "9                 2.0                      0.484848   \n",
       "\n",
       "   AWAY_LAST_GAME_TOTAL_WIN_PCTG  AWAY_LAST_GAME_ROLLING_SCORING_MARGIN  \\\n",
       "0                       0.239437                              -2.000000   \n",
       "1                       0.304348                             -18.000000   \n",
       "2                       0.463768                               0.666667   \n",
       "3                       0.470588                               0.666667   \n",
       "4                       0.552239                              17.333333   \n",
       "5                       0.723077                              13.333333   \n",
       "6                       0.562500                              16.666667   \n",
       "7                       0.412698                              -7.000000   \n",
       "8                       0.539683                             -17.000000   \n",
       "9                       0.548387                               2.666667   \n",
       "\n",
       "   AWAY_LAST_GAME_ROLLING_OE  \n",
       "0                   0.605315  \n",
       "1                   0.512228  \n",
       "2                   0.567718  \n",
       "3                   0.570866  \n",
       "4                   0.633081  \n",
       "5                   0.644613  \n",
       "6                   0.599989  \n",
       "7                   0.568524  \n",
       "8                   0.489968  \n",
       "9                   0.540221  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = pd.read_csv('nbaHomeWinLossModelDataset.csv').drop(['Unnamed: 0'],axis=1)\n",
    "data = data.dropna()\n",
    "data.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "validation = data[data['SEASON'] == '2022-23']\n",
    "modelData = data[data['SEASON'] != '2022-23'].sample(frac=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = modelData.drop(['HOME_W','SEASON'],axis=1)\n",
    "y = modelData['HOME_W']\n",
    "X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=.33)\n",
    "\n",
    "# Standard Scaling Prediction Variables\n",
    "scaler = preprocessing.StandardScaler()\n",
    "scaler.fit(X_train)\n",
    "scaled_data_train = scaler.transform(X_train)\n",
    "\n",
    "scaler.fit(X_test)\n",
    "scaled_data_test = scaler.transform(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.614441416893733"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Logistic Regression\n",
    "\n",
    "model = LogisticRegression()\n",
    "model.fit(scaled_data_train,y_train)\n",
    "model.score(scaled_data_test,y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Logistic Model F1 Accuracy: 0.61 (+/- 0.12)\n"
     ]
    }
   ],
   "source": [
    "F1Score = cross_val_score(model,scaled_data_test,y_test,cv=12,scoring='f1_macro');\n",
    "print(\"Logistic Model F1 Accuracy: %0.2f (+/- %0.2f)\"%(F1Score.mean(), F1Score.std() *2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.60      0.47      0.53       336\n",
      "           1       0.62      0.74      0.68       398\n",
      "\n",
      "    accuracy                           0.61       734\n",
      "   macro avg       0.61      0.60      0.60       734\n",
      "weighted avg       0.61      0.61      0.61       734\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Test Set Review\n",
    "\n",
    "y_pred = model.predict(scaled_data_test)\n",
    "print(classification_report(y_test,y_pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Validation Set review\n",
    "\n",
    "# Standard Scaling Prediction Variables\n",
    "scaler = preprocessing.StandardScaler()\n",
    "scaler.fit(validation.drop(['HOME_W','SEASON'],axis=1))\n",
    "scaled_val_data = scaler.transform(validation.drop(['HOME_W','SEASON'],axis=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.49      0.47      0.48       210\n",
      "           1       0.68      0.70      0.69       338\n",
      "\n",
      "    accuracy                           0.61       548\n",
      "   macro avg       0.59      0.59      0.59       548\n",
      "weighted avg       0.61      0.61      0.61       548\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# How the model performs on unseen data\n",
    "y_pred = model.predict(scaled_val_data)\n",
    "print(classification_report(validation['HOME_W'],y_pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
